home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 140
/
Gekkan Dennou Club - 2000.1 Vol. 140 (Japan).7z
/
Gekkan Dennou Club - 2000.1 Vol. 140 (Japan) (Track 1).bin
/
games
/
oyatsu
/
src
/
screen.c
< prev
next >
Wrap
Text File
|
1999-11-22
|
15KB
|
568 lines
/****************************************
推理パズル「おやつタイム」
画面
****************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys\iocs.h>
#include "oyatsu.h"
#include "screen.h"
#include "pad.h"
#include "sprite.h"
#define SPRITE_FILE "OYATSU" /* スプライトデータ */
#define MESSAGE_SX 10 /* メッセージ表示位置 */
#define MESSAGE_SY 2
#define ANSWER_X 64 /* 回答表示位置 */
#define ANSWER_Y 330
#define ANSWER2_X (ANSWER_X + 216) /* 解答表示位置 */
#define ANSWER2_Y ANSWER_Y
#define ANSWER_DX 48 /* キャラクタの間隔 */
#define ANSWER_DY 48
#define SELECT_X (ANSWER_X + 200) /* キャラクタ選択用 */
#define SELECT_Y (ANSWER_Y + 32)
#define SELECT_DX 40 /* キャラクタの間隔 */
#define SELECT_DY 42
#define KETTEI_X ANSWER_X /* [決定]ボタン */
#define KETTEI_Y (ANSWER_Y + ANSWER_DY*3)
/*** スプライトナンバー *****/
#define NUM_CURSOR 0
#define NUM_ANSWER (NUM_CURSOR + 4)
#define NUM_RIGHT_ANS (NUM_ANSWER + 32)
#define NUM_OK (NUM_RIGHT_ANS + 32)
/*** スプライトコード *****/
#define SPR_GIRL 0x100 /* 顔 */
#define SPR_INPUT 0x999 /* 入力位置 */
#define SPR_OK 0x59a /* 決定ボタン */
#define BG_PATTERN 0x6a0 /* 背景パターン */
#define FOOD_MAX 19 /* 菓子の種類 */
#define BACK_MAX 0x30 /* 背景パターンの数 */
#define SPRITE_REG (unsigned short*)0xeb0000 /* スプライトレジスタアドレス */
static unsigned short food_code[FOOD_MAX] = { /* 菓子スプライト */
0xb80, 0xb81, 0xb82, 0xb83, 0xb84, 0xb85, 0xc86, 0xc87,
0xc88, 0x789, 0x78a, 0x88b, 0x88c, 0x88d, 0x88e, 0x88f,
0xa90, 0xa91, 0xa92
};
static int cursor_x, cursor_y; /* 文字表示位置 */
static unsigned short food_kind[GIRL_MAX]; /* 菓子の種類 */
static char sprite_buf[0x8000]; /* スプライトデータ */
static unsigned short palet_buf[0x100]; /* パレットデータ */
/**********************
垂直帰線期間待ち
**********************/
void v_synch(void)
{
pad_synch(); /* パッド同期処理 */
rand(); /* 乱数 */
while ( !(_iocs_b_bpeek((void *)0xe88001) & 0x10) ); /* 垂直帰線期間 */
while ( _iocs_b_bpeek((void *)0xe88001) & 0x10 ); /* 垂直表示期間 */
}
/***************************************
スプライト描画
引数 num = スプライト番号
code = パターンコード
x, y = 表示位置
***************************************/
static
void put_sprite(int num, unsigned short code, int x, int y)
{
unsigned short* p;
p = SPRITE_REG + num*4; /* スプライトレジスタ */
*p++ = (unsigned short)x; /* x座標 */
*p++ = (unsigned short)y; /* y座標 */
*p++ = code; /* パターンコード */
*p = 3; /* プライオリティ */
}
/**************************************
スプライト消去
引数 num = スプライト番号
**************************************/
static
void clear_sprite(int num)
{
*(SPRITE_REG + num*4 + 3) = 0; /* スプライト非表示 */
}
/***************************************
スプライト顔描画
引数 num = スプライト番号
girl = 人
x, y = 表示位置
***************************************/
static
void draw_girl_spr(int num, int girl, int x, int y)
{
int ssp, code;
ssp = _iocs_b_super(0); /* スーパーバイザモード */
if ( girl >= 0 ) { /* 顔 */
code = SPR_GIRL + girl*0x120;
put_sprite(num++, code, x + 16, y + 16);
put_sprite(num++, code + 0x01, x + 32, y + 16);
put_sprite(num++, code + 0x10, x + 16, y + 32);
put_sprite(num, code + 0x11, x + 32, y + 32);
}
else { /* 入力位置 */
put_sprite(num++, SPR_INPUT, x + 8 + 16, y + 8 + 16);
clear_sprite(num++);
clear_sprite(num++);
clear_sprite(num);
}
_iocs_b_super(ssp); /* ユーザーモード */
}
/*********************************
顔表示
引数 girl = 人
exp = 表情
x, y = 表示位置
*********************************/
static
void draw_girl(int girl, int exp, int x, int y)
{
int ssp;
char* pat;
unsigned short* pal;
ssp = _iocs_b_super(0); /* スーパーバイザモード */
pat = sprite_buf + ((SPR_GIRL % 0x100) + girl*0x20 + exp*2)*0x80;
/* パターン */
pal = palet_buf + (SPR_GIRL/0x100 - 1 + girl)*0x10; /* パレット */
draw_g_sprite(x, y, pat, pal);
draw_g_sprite(x + 16, y, pat + 0x01*0x80, pal);
draw_g_sprite(x, y + 16, pat + 0x10*0x80, pal);
draw_g_sprite(x + 16, y + 16, pat + 0x11*0x80, pal);
_iocs_b_super(ssp); /* ユーザーモード */
}
/*********************************
菓子表示
引数 food = 菓子
x, y = 表示位置
*********************************/
static
void draw_food(int food, int x, int y)
{
int ssp, code;
ssp = _iocs_b_super(0); /* スーパーバイザモード */
code = food_kind[food]; /* スプライトコード */
draw_g_sprite2(x, y, sprite_buf + (code % 0x100)*0x80,
palet_buf + (code/0x100 - 1)*0x10);
_iocs_b_super(ssp); /* ユーザーモード */
}
/************************************
メッセージ表示
引数 girl = 発言者番号
mes = メッセージ
num = 要素番号
戻り値 表示位置
***********************************/
int print_message(int girl, MESSAGE* mes, int* num)
{
char buf[80], *p0, *p1;
int pos;
pos = cursor_y*16 - 12;
draw_girl(girl, mes->exp, MESSAGE_SX*8 - 48, pos); /* 発言者表示 */
_iocs_b_locate(cursor_x - 2, cursor_y);
_iocs_b_print("「");
p0 = mes->str; /* メッセージ文章 */
while (1) {
_iocs_b_locate(cursor_x, cursor_y); /* 表示位置 */
p1 = buf;
while ( (unsigned char)*p0 >= 0x80 ) {
*p1++ = *p0++;
*p1++ = *p0++;
cursor_x += 2;
}
*p1 = '\0';
_iocs_b_print(buf); /* 文字列表示 */
if ( *p0 == '\0' ) { /* 終端 */
break;
}
if ( *p0 == '\n' ) { /* 改行 */
cursor_x = MESSAGE_SX;
cursor_y += 2;
}
else if ( *p0 == '#' ) { /* 菓子 */
p0++;
draw_food(num[*p0 - '0'], cursor_x*8, cursor_y*16 - 12);
cursor_x += 4;
}
else if ( *p0 == '$' ) { /* 人 */
p0++;
draw_girl(num[*p0 - '0'], 0, cursor_x*8, cursor_y*16 - 12);
cursor_x += 4;
}
p0++;
}
_iocs_b_print("」");
cursor_x = MESSAGE_SX;
cursor_y += 3;
return pos;
}
/*********************************
答表示
引数 kind = 0 : 回答
1 : 解答
ans = 答
*********************************/
void draw_answer(int kind, int ans[ELM_MAX][GIRL_MAX])
{
int i, x, num;
if ( kind == 0 ) { /* 回答 */
num = NUM_ANSWER;
x = ANSWER_X;
}
else { /* 解答 */
num = NUM_RIGHT_ANS;
x = ANSWER2_X;
}
for (i = 0; i < GIRL_MAX; i++) {
draw_food(i, x, ANSWER_Y); /* 菓子 */
draw_girl_spr(num, ans[ELM_BUY][i], x, ANSWER_Y + ANSWER_DY); /* 買った人 */
num += 4;
draw_girl_spr(num, ans[ELM_EAT][i], x, ANSWER_Y + ANSWER_DY*2); /* 食べた人 */
num += 4;
x += ANSWER_DX;
}
}
/**************************************
決定ボタン描画
引数 f = 全て入力されたか
**************************************/
static
void draw_ok_button(Bool f)
{
int ssp, i;
ssp = _iocs_b_super(0); /* スーパーバイザモード */
if ( f ) { /* ボタン描画 */
for (i = 0; i < 6; i++) {
put_sprite(NUM_OK + i, SPR_OK + i, KETTEI_X + (i % 3)*16 + 16,
KETTEI_Y + i/3*16 + 16);
}
}
else { /* ボタン消去 */
for (i = 0; i < 6; i++) {
clear_sprite(NUM_OK + i);
}
}
_iocs_b_super(ssp); /* ユーザーモード */
}
/*********************************************
入力処理
引数 ans = 回答バッファ
select = 選択キャラクタ
f = 全て入力されたか
x, y = マウスカーソル位置
戻り値 選択キャラクタ
-1 : 入力完了
*********************************************/
static
int input_sub(int ans[ELM_MAX][GIRL_MAX], int select, Bool f, int x, int y)
{
int i, m, n;
if ( f && (x >= KETTEI_X) && (x < KETTEI_X + 16*3)
&& (y >= KETTEI_Y) && (y < KETTEI_Y + 16*2) ) {
return -1; /* 入力完了 */
}
m = x - (ANSWER_X - (ANSWER_DX - 32)/2);
n = y - (ANSWER_Y + ANSWER_DY - (ANSWER_DY - 32)/2);
if ( (m >= 0) && (m < GIRL_MAX*ANSWER_DX) && (n >= 0) && (n < 2*ANSWER_DY) ) {
/* 回答入力 */
m /= ANSWER_DX;
n /= ANSWER_DY;
for (i = 0; i < GIRL_MAX; i++) {
if ( ans[n][i] == select ) {
ans[n][i] = -1;
}
}
ans[n][m] = select;
return select;
}
m = x - (SELECT_X - (SELECT_DX - 32)/2);
n = y - (SELECT_Y - (SELECT_DY - 32)/2);
if ( (m >= 0) && (m < (GIRL_MAX/2)*SELECT_DX) && (n >= 0) && (n < 2*SELECT_DY) ) {
/* キャラクタ選択 */
return ((n/SELECT_DY)*(GIRL_MAX/2) + m/SELECT_DX);
}
return select;
}
/************************************
回答入力
引数 ans = 回答バッファ
戻り値 0 : 入力完了
-1 : ゲーム終了
************************************/
int input_answer(int ans[ELM_MAX][GIRL_MAX])
{
static struct _symbolptr katta = {ANSWER_X - 36, ANSWER_Y + ANSWER_DY + 4,
"買", 1, 1, 0xfd38, 2, 0},
tabeta = {ANSWER_X - 36, ANSWER_Y + ANSWER_DY*2 + 4,
"食", 1, 1, 0xffe8, 2, 0};
int ssp;
int i, j, *p, select;
Bool f;
p = &ans[0][0]; /* 回答バッファ */
for (i = 0; i < ELM_MAX*GIRL_MAX; i++) {
*p++ = -1; /* 未入力 */
}
select= 0; /* 選択中キャラクタ */
for (i = 0; i < GIRL_MAX; i++) { /* 選択用キャラクタ表示 */
draw_girl_spr(NUM_RIGHT_ANS + i*4, i,
SELECT_X + (i % (GIRL_MAX/2))*SELECT_DX,
SELECT_Y + (i/(GIRL_MAX/2))*SELECT_DY);
}
_iocs_symbol(&katta); /* "買" */
_iocs_symbol(&tabeta); /* "食" */
while (1) {
v_synch(); /* 垂直同期 */
if ( esc_key ) {
return -1; /* ゲーム終了 */
}
p = &ans[0][0]; /* 回答バッファ */
f = TRUE;
for (i = 0; i < ELM_MAX*GIRL_MAX; i++) {
if ( *p++ < 0 ) { /* 未入力 */
f = FALSE;
break;
}
}
draw_ok_button(f); /* 決定ボタン */
draw_answer(0, ans); /* 回答表示 */
get_ms_pos(&i, &j); /* マウスカーソル位置 */
draw_girl_spr(NUM_CURSOR, select, i - 16, j - 16); /* カーソル表示 */
if ( get_push() & PAD_A ) { /* 左クリック */
if ( (select = input_sub(ans, select, f, i, j)) < 0 ) {
break;
}
}
if ( get_push() & PAD_B ) { /* 右クリック */
select = (select + 1) % GIRL_MAX; /* 選択キャラクター切り替え */
}
}
ssp = _iocs_b_super(0); /* スーパーバイザモード */
for (i = 0; i < 4; i++) { /* カーソル消去 */
clear_sprite(NUM_CURSOR + i);
}
_iocs_b_super(ssp); /* ユーザーモード */
return 0;
}
/******************
「正解」表示
******************/
void draw_atari(void)
{
static struct _symbolptr atari = {ANSWER_X + 28, ANSWER_Y - 20,
"正 解", 2, 3, 0x67d8, 2, 0};
_iocs_symbol(&atari); /* "正解" */
}
/********************************
条件に合っていない
引数 pos = 表示位置
********************************/
void draw_mujun1(int pos)
{
static struct _boxptr box = {MESSAGE_SX*8 - 50, 0, MESSAGE_SX*8 - 14, 0,
0x67d8, 0xffff};
box.y1 = pos - 3;
box.y2 = pos + 35;
_iocs_box(&box); /* 赤枠で囲む */
}
/********************************
前提に合っていない
引数 num = 菓子番号
********************************/
void draw_mujun2(int num)
{
static struct _boxptr box = {0, ANSWER_Y + ANSWER_DY - 3,
0, ANSWER_Y + ANSWER_DY*2 + 35, 0x67d8, 0xffff};
box.x1 = ANSWER_X + num*ANSWER_DX - 2;
box.x2 = ANSWER_X + num*ANSWER_DX + 34;
_iocs_box(&box); /* 赤枠で囲む */
}
/****************
画面クリア
****************/
void clear_screen(void)
{
int ssp;
char* pat;
unsigned short* pal;
int i, j;
_iocs_b_clr_al(); /* テキスト画面クリア */
cursor_x = MESSAGE_SX; /* カーソル位置 */
cursor_y = MESSAGE_SY;
ssp = _iocs_b_super(0); /* スーパーバイザモード */
for (i = 0; i < 0x80; i++) {
clear_sprite(i); /* スプライト非表示 */
}
pat = sprite_buf + ((BG_PATTERN % 0x100) + rnd(BACK_MAX))*0x80; /* パターン */
pal = palet_buf + (BG_PATTERN/0x100 - 1)*0x10; /* パレット */
for (i = 0; i < 0x200; i += 0x20) { /* 背景クリア */
for (j = 0; j < 0x200; j += 0x20) {
draw_g_sprite2(j, i, pat, pal);
}
}
_iocs_b_super(ssp); /* ユーザーモード */
}
/**************
菓子設定
**************/
void set_food(void)
{
unsigned short code;
int i, j;
for (i = 0; i < GIRL_MAX; i++) {
do {
code = food_code[rnd(FOOD_MAX)]; /* 菓子スプライト */
for (j = 0; j < i; j++) {
if ( code == food_kind[j] ) { /* 重複 */
break;
}
}
} while ( j < i );
food_kind[i] = code; /* 使用する菓子の種類 */
}
}
/****************************************
スプライトデータ読み込み
引数 fname = ファイルネーム
戻り値 0 : 読み込み完了
1 : 読み込み失敗
****************************************/
static
int load_sprite(char* fname)
{
FILE* fp;
char buf[256], *p;
unsigned short* c;
int i, j, size;
_iocs_sp_init(); /* スプライト画面初期化 */
_iocs_sp_on(); /* スプライト画面表示 */
sprintf(buf, "%s.SP", fname); /* パターンデータ */
if ( (fp = fopen(buf, "rb")) == NULL ) {
eprintf("パターンファイル \"%s\" が開けません\n", buf);
return 1;
}
printf("\"%s\" 読み込み中\n", buf);
size = fread(sprite_buf, 0x80, 0x100, fp);
fclose(fp);
for (i = 0, p = sprite_buf; i < size; i++, p += 0x80) {
_iocs_sp_defcg(i, 1, p); /* スプライト定義 */
}
sprintf(buf, "%s.PAL", fname); /* パレットデータ */
if ( (fp = fopen(buf, "rb")) == NULL ) {
eprintf("パレットファイル \"%s\" が開けません\n", buf);
return 1;
}
printf("\"%s\" 読み込み中\n", buf);
size = fread(palet_buf, sizeof(short)*0x10, 0x0f, fp);
fclose(fp);
c = palet_buf;
for (j = 0; j < size; j++) {
for (i = 0; i < 0x10; i++) {
_iocs_spalet(i + 0x80, j + 1, (int)*c++); /* パレット定義 */
}
}
_iocs_b_clr_al(); /* 画面クリア */
return 0;
}
/******************
マウス初期化
******************/
static
void init_mouse(void)
{
_iocs_ms_init(); /* マウス初期化 */
_iocs_ms_curst(ANSWER_X, ANSWER_Y); /* マウスカーソル座標 */
_iocs_ms_curof(); /* マウスカーソルOFF */
}
/********************************
画面初期化
戻り値 0 : 初期化完了
1 : 初期化失敗
********************************/
int init_screen(void)
{
init_mouse(); /* マウス初期化 */
if ( load_sprite(SPRITE_FILE) ) { /* スプライト読み込み */
return 1;
}
_iocs_b_bpoke((void*)0xe82500, 0x12); /* プライオリティ設定 */
return 0;
}
/****************** End of File *************************************************/